package hu.cskassai.sad.gui.frames;

import hu.cskassai.sad.business.GraphManager;
import hu.cskassai.sad.business.internal.GraphManagerImpl;
import hu.cskassai.sad.business.requests.SaveGraphRequest;
import hu.cskassai.sad.gui.panels.AlgorithmChooserPanel;
import hu.cskassai.sad.gui.panels.AlgorithmDetailPanel;
import hu.cskassai.sad.gui.panels.GraphVisualizerPanel;
import hu.cskassai.sad.model.graph.Edge;
import hu.cskassai.sad.model.graph.Vertex2D;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.HeadlessException;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.Collection;

import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;

import edu.uci.ics.jung.algorithms.layout.Layout;
import edu.uci.ics.jung.algorithms.layout.StaticLayout;
import edu.uci.ics.jung.visualization.RenderContext;

public class MainFrame extends JFrame {
	
	private final GraphManager<Vertex2D, Edge> graphManager = new GraphManagerImpl();
	
	private final GraphVisualizerPanel graphVisualizerPanel;
	
	public void setFilePath(final String filePath) {
		this.filePath = filePath;
	}
	
	private final AlgorithmDetailPanel algorithmDetailPanel;
	
	private String filePath = null;
	
	public MainFrame() throws HeadlessException {
		super("Search Algorithm Demostrator");
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		final Toolkit defaultToolkit = Toolkit.getDefaultToolkit();
		
		final Layout<Vertex2D, Edge> layout = new StaticLayout<Vertex2D, Edge>(graphManager.getGraph(),
			defaultToolkit.getScreenSize());
		this.setLayout(new BorderLayout());
		layout.setInitializer(graphManager.getVertexToPointTransformer());
		
		final int screenWidht = defaultToolkit.getScreenSize().width;
		graphVisualizerPanel = new GraphVisualizerPanel(layout, new Dimension(screenWidht - 200,
			defaultToolkit.getScreenSize().height - 200), graphManager, this);
		this.getContentPane().add(graphVisualizerPanel, BorderLayout.CENTER);
		
		final AlgorithmChooserPanel algorithmChooserPanel = new AlgorithmChooserPanel(this, graphManager);
		algorithmChooserPanel.setPreferredSize(new Dimension(screenWidht - 200, 200));
		algorithmChooserPanel.setVisible(true);
		this.getContentPane().add(algorithmChooserPanel, BorderLayout.NORTH);
		
		algorithmDetailPanel = new AlgorithmDetailPanel(graphManager);
		algorithmDetailPanel.setPreferredSize(new Dimension(300,
			defaultToolkit.getScreenSize().height));
		algorithmDetailPanel.setVisible(true);
		this.getContentPane().add(algorithmDetailPanel, BorderLayout.EAST);
		
		final JMenuBar jMenuBar = new JMenuBar();
		final JMenu fileMenu = new JMenu("File");
		jMenuBar.add(fileMenu);
		final JMenuItem newGraphJMenuItem = new JMenuItem("New Graph");
		newGraphJMenuItem.addActionListener(new ActionListener() {
			
			public void actionPerformed(final ActionEvent arg0) {
				graphManager.newGraph();
				changeGraph();
				
			}
		});
		fileMenu.add(newGraphJMenuItem);
		final JMenuItem saveGraphJMenuItem = new JMenuItem("Save graph");
		saveGraphJMenuItem.addActionListener(new ActionListener() {
			
			public void actionPerformed(final ActionEvent e) {
				String fileName = null;
				if (filePath == null) {
					final JFileChooser fc = new JFileChooser();
					fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
					final int returnVal = fc.showDialog(fc, "Save");
					try {
						if (returnVal == JFileChooser.APPROVE_OPTION) {
							final File file = fc.getSelectedFile();
							filePath = file.getAbsolutePath();
							fileName = file.getName();
							algorithmChooserPanel.refresh();
						}
						
					} catch (final Exception ex) {
						
					}
				}
				
				final SaveGraphRequest request = new SaveGraphRequest();
				request.setFilePath(filePath);
				request.setName(fileName);
				graphManager.saveGraph(request);
				
			}
		});
		fileMenu.add(saveGraphJMenuItem);
		final JMenuItem saveAsGraphJMenuItem = new JMenuItem("Save Graph As");
		saveAsGraphJMenuItem.addActionListener(new ActionListener() {
			
			public void actionPerformed(final ActionEvent e) {
				String fileName = null;
				
				final JFileChooser fc = new JFileChooser();
				fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
				final int returnVal = fc.showDialog(fc, "Save");
				try {
					if (returnVal == JFileChooser.APPROVE_OPTION) {
						final File file = fc.getSelectedFile();
						filePath = file.getAbsolutePath();
						fileName = file.getName();
						algorithmChooserPanel.refresh();
					}
					
				} catch (final Exception ex) {
					
				}
				
				final SaveGraphRequest request = new SaveGraphRequest();
				request.setFilePath(filePath);
				request.setName(fileName);
				graphManager.saveGraph(request);
				
			}
		});
		fileMenu.add(saveAsGraphJMenuItem);
		this.setJMenuBar(jMenuBar);
		this.setExtendedState(JFrame.MAXIMIZED_BOTH);
		this.pack();
		this.setVisible(true);
		
	}
	
	public void changeAlgorithm() {
		final RenderContext<Vertex2D, Edge> renderContext = graphVisualizerPanel.getRenderContext();
		
		renderContext.setEdgeDrawPaintTransformer(graphManager.getEdgeColorTransformer());
		renderContext.setVertexFillPaintTransformer(graphManager.getVertexColorTransformer());
		graphVisualizerPanel.repaint();
	}
	
	public void stepRefresh() {
		algorithmDetailPanel.refresh();
	}
	
	public static void main(final String[] args) {
		final MainFrame mainFrame = new MainFrame();
	}
	
	public void changeGraph() {
		graphVisualizerPanel.changeGraph();
	}
	
	public void setVertexProperties(final Collection<Object[]> properties) {
		algorithmDetailPanel.setVertexProperties(properties);
	}
	
}
